package cn.base.web.auth.realm;


import cn.base.web.cahe.TemporaryCache;
import cn.base.web.config.LoginProperties;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.rengy.auth.Authentication;
import cn.rengy.auth.AuthenToken;
import cn.rengy.auth.SimpleAuthenInfo;
import cn.rengy.auth.entity.SessionEntity;
import cn.rengy.auth.entity.principal.Identity;
import cn.rengy.auth.exception.AuthException;
import cn.rengy.auth.jwt.JwtCreator;
import cn.rengy.auth.realm.AbstractAuthenRealm;
import cn.rengy.auth.token.JwtToken;
import cn.rengy.util.web.RequestUtil;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;

/**
 * 持久化的token认证，
 * 使用永不过期的jwt做为token，jwt携带数据方便
 * @author rengy
 *
 */
@Component
@Slf4j
public class StoredTokenAuthenRealm extends AbstractAuthenRealm {
    @Override
    public String getName() {
        return "StoredTokenAuthenRealm";
    }

    public boolean supports(AuthenToken token) {
        return token.getClass() == JwtToken.class;
    }

    @Resource
    private TemporaryCache temporaryCache;
    @Autowired
    private LoginProperties loginProperties;
    @Override
    public Authentication getAuthenticationInfo(AuthenToken authenticationToken) throws AuthException {
        if (!supports(authenticationToken)) {
        	log.error("error token： {}",authenticationToken.getClass().getName());
            throw new AuthException(401,"错误的token登陆");
        }
        //ExpiredCredentialsException 凭据已失效
        //IncorrectCredentialsException 凭据与主体不匹配
        JwtToken jwtToken = (JwtToken)authenticationToken;
        String jwt = jwtToken.getJwt();
        Identity identity=null;
        try {
        	identity= JwtCreator.parseToken(jwt);
        }catch(ExpiredJwtException e) {
            //没有设置有效期,不会出现这种情况
        	throw new AuthException(401,"token已过期");
        }catch(JwtException e) {
            //jwt是后端生成的，不会出现解析错误
        	log.warn("jwt解析错误：{}",e.getMessage());
        	throw new AuthException(401,"jwt解析错误");
        }
        String id=generateSessionId(identity.getSessionId());
        SessionEntity sessionEntity =(SessionEntity)temporaryCache.getAndExpire(id,loginProperties.getTokenTimeout());
        if(sessionEntity==null){
            throw new AuthException(401,"token已过期");
        }
//        Date lastAccessedTime=sessionEntity.getLastAccessedTime();
//        Date now=new Date();
//        long time=DateUtil.between(lastAccessedTime,now, DateUnit.MINUTE);
//        if(time>loginProperties.getTokenRefreshTime().toMinutes()){
//
//            //刷新token
//            sessionEntity.setLastAccessedTime(now);
//            redisTemplate.opsForValue().set(id, sessionEntity, loginProperties.getTokenTimeout());
//        }
        //校验客户端ip和useragent
        if(!jwtToken.getClientId().equals(identity.getClientId())) {
            log.warn("客户端ip已改变");
        	//throw new AuthenticationException("客户端ip已改变，请重新登录");
        }
        //UserContextHolder.set(identity);
        RequestUtil.setPrincipal(identity);
        return new SimpleAuthenInfo(identity,jwt, getName());
    }
}
